package de.openlaboratory.elib.core;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.Singleton;
import javax.ejb.Startup;

import org.hibernate.cfg.Configuration;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import static javax.ejb.ConcurrencyManagementType.BEAN;

// Singleton beans with @ConcurrencyManagement(BEAN)
// are responsible for their own thread-safety

@Singleton
@Startup
@ConcurrencyManagement(BEAN)
public class PropertyRegistry
{
	// Note the java.util.Properties object is a thread-safe
	// collections that uses synchronization. If it didn't
	// you would have to use some form of synchronization
	// to ensure the PropertyRegistryBean is thread-safe.
	private final Properties properties = new Properties();

	// The @Startup method ensures that this method is
	// called when the application starts up.
	@PostConstruct
	public void applicationStartup()
	{
		properties.putAll(System.getProperties());
	}

	@PreDestroy
	public void applicationShutdown()
	{
		properties.clear();
	}

	public String getProperty(String key)
	{
		return properties.getProperty(key);
	}

	public String setProperty(String key, String value)
	{
		return (String) properties.setProperty(key, value);
	}

	public String removeProperty(String key)
	{
		return (String) properties.remove(key);
	}

	public static String[] getHibernateModel()
	{
		List<String> classes = new ArrayList<String>();

		classes.add("de.openlaboratory.elib.model.library");
		classes.add("de.openlaboratory.elib.model.system");

		String[] classArray = new String[classes.size()];

		classArray = (String[]) classes.toArray(new String[classes.size()]);

		return classArray;
	}

	public static Configuration getInitializedHibernateConfiguration()
	{
		// String SQLITE_CLASS = "org.sqlite.JDBC";
		// String SQLITE_URL =
		// "jdbc:sqlite:D:/DEV/openlaboratory/DB/sqlite/jdbc-test.db";
		// String SQLITE_DIALECT =
		// "de.openlaboratory.elib.database.hibernate.HibernateDialectSqlite";
		// String SQLITE_USER = "";
		// String SQLITE_PASS = "";

		Configuration config = new Configuration();

		/**
		 * WARNING: standard parameters MUST contain "hibernate." prefix to work
		 * properly.
		 */

		String MYSQL_CLASS = "com.mysql.jdbc.Driver";
		String MYSQL_URL = "jdbc:mysql://localhost/elib";
		String MYSQL_DIALECT = "org.hibernate.dialect.MySQL5InnoDBDialect";
		String MYSQL_USER = "elib";
		String MYSQL_PASS = "elib";

		LogManager.logMessage("Hibernate configuration: [" + MYSQL_CLASS + "/" + MYSQL_URL + "]");

		config.setProperty("hibernate.connection.driver_class", MYSQL_CLASS);
		config.setProperty("hibernate.connection.url", MYSQL_URL);
		config.setProperty("hibernate.connection.username", MYSQL_USER);
		config.setProperty("hibernate.connection.password", MYSQL_PASS);
		config.setProperty("hibernate.dialect", MYSQL_DIALECT);
		config.setProperty("hibernate.connection.pool_size", "1");
		config.setProperty("hibernate.current_session_context_class", "thread");
		config.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider");
		config.setProperty("hibernate.show_sql", "true");
		config.setProperty("hibernate.format_sql", "true");

		config.setProperty("hibernate.connection.autoReconnect", "true");
		
		// Drop and re-create the database schema on startup
		config.setProperty("hibernate.hbm2ddl.auto", "update");
		
		// AUTOCOMMIT is not needed if GenericDataServlet is used
		// config.setProperty("hibernate.connection.autocommit", "true");

		// config.setProperty("org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator","org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider");
		// config.setProperty("hibernate.connection.username", "jaikoz");
		// config.setProperty("hibernate.c3p0.min_size", "20");
		// config.setProperty("hibernate.c3p0.max_size", "100");
		// config.setProperty("hibernate.c3p0.timeout", "300");
		// config.setProperty("hibernate.c3p0.max_statements", "50");
		// config.setProperty("hibernate.c3p0.idle_test_period", "3000");
		// config.setProperty("hibernate.show_sql", "true");
		// config.setProperty("hibernate.ejb.event.post-insert",
		// "org.hibernate.envers.event.AuditEventListener");
		// config.setProperty("hibernate.ejb.event.post-update",
		// "org.hibernate.envers.event.AuditEventListener");
		// config.setProperty("hibernate.ejb.event.post-delete",
		// "org.hibernate.envers.event.AuditEventListener");
		// config.setProperty("hibernate.ejb.event.pre-collection-update",
		// "org.hibernate.envers.event.AuditEventListener");
		// config.setProperty("hibernate.ejb.event.pre-collection-remove",
		// "org.hibernate.envers.event.AuditEventListener");
		// config.setProperty("hibernate.ejb.event.post-collection-recreate",
		// "org.hibernate.envers.event.AuditEventListener");

		// addAnnotatedClasses
		// for (String pack : PropertyRegistry.getHibernateModel())
		// {
		// LogManager.logMessage("add package [" + pack + "]");
		// config.addPackage(pack);
		// }

		config.addAnnotatedClass(de.openlaboratory.elib.model.library.Publication.class);
		config.addAnnotatedClass(de.openlaboratory.elib.model.library.Library.class);
		config.addAnnotatedClass(de.openlaboratory.elib.model.library.Author.class);

		return config;
	}

}